// 导入 React 及 useState hook
import React, { useState } from "react"
// 导入样式文件
import './compute.sass'

/**
 * Compute 组件，实现一个计算器功能
 */
function Compute() {
  // 定义计算器按钮配置数组
  const arr = [
    { value: '-/+', type: 'reverse' },
    { value: '÷', type: 'operator', realOperator: '/' },
    { value: 7, type: 'number' },
    { value: 8, type: 'number' },
    { value: 9, type: 'number' },
    { value: '×', type: 'operator', realOperator: '*' },
    { value: 4, type: 'number' },
    { value: 5, type: 'number' },
    { value: 6, type: 'number' },
    { value: '－', type: 'operator', realOperator: '-' },
    { value: 1, type: 'number' },
    { value: 2, type: 'number' },
    { value: 3, type: 'number' },
    { value: '＋', type: 'operator', realOperator: '+' },
    { value: '%', type: 'precent' },
    { value: 0, type: 'number' },
    { value: '.', type: 'dot' },
    { value: '=', type: 'result' }
  ]
  // 存储计算结果字符串
  const [ result, setResult ] = useState('')
  // 存储计算器当前状态
  const [ value, setValue ] = useState({
    canAdd: false, // 是否可以添加下一项
    canRes: false, // 是否可以计算结果
    isFinished: false, // 计算是否完成
    values: [{ value: '', operator: '+', realOperator: '+', hasDot: false, reverse: false }]
  }) // { hasDot: false, canRes: false, values: [ { value: 00, operator: '+' } ] }

  /**
   * 处理按钮点击事件，更新计算器状态
   * @param {Object} v - 按钮配置对象
   */
  function computedValue (v) {
    // 复制当前状态
    const oldVal = {...value}
    let current
    switch (v.type) {
      case 'number':
        // 如果计算已完成，重置状态
        if (oldVal.isFinished) {
          oldVal.values = [{ value: '', operator: '+', realOperator: '+', hasDot: false, reverse: false }]
          oldVal.canAdd = false
          oldVal.canRes = false
          oldVal.isFinished = false
          setResult('')
        }
        // 获取当前操作数
        current = oldVal.values[oldVal.values.length - 1]
        // 如果是反转状态
        if (current.reverse) {
          current.value = current.value.slice(1, -1)
        }
        // 更新当前操作数
        if (current.hasDot) {
          current.value = String(current.value + v.value)
        } else {
          current.value = Number((current.value) + v.value).toString()
        }
        if (current.reverse) {
          current.value = `(${current.value})`
        }
        oldVal.canAdd = true
        // console.log(oldVal)
        break
      case 'dot':
        // 如果计算已完成，重置状态
        if (oldVal.isFinished) {
          oldVal.values = [{ value: eval(result).toString(), operator: '+', realOperator: '+', hasDot: false, reverse: false }]
          oldVal.canAdd = false
          oldVal.canRes = false
          oldVal.isFinished = false
          setResult('')
        }
        current = oldVal.values[oldVal.values.length - 1]
        // 如果是反转状态或已经有小数点则不处理
        if (current.reverse) {
          current.value = current.value.slice(1, -1)
        }
        if (current.hasDot) return
        // 添加小数点
        current.value = current.value + v.value
        current.hasDot = true
        if (current.reverse) {
          current.value = `(${current.value})`
        }
        oldVal.canAdd = true
        break
      case 'result':
        // 如果不能计算结果则不处理
        if (!oldVal.canRes) return
        // 标记计算完成
        oldVal.isFinished = true
        break
      case 'operator':
        // 如果计算已完成，重置状态
        if (oldVal.isFinished) {
          oldVal.values = [{ value: eval(result).toString(), operator: '+', realOperator: '+', hasDot: false, reverse: false }]
          oldVal.canAdd = true
          oldVal.canRes = false
          oldVal.isFinished = false
          setResult('')
        }
        // console.log(oldVal)
        if (oldVal.canAdd) {
          oldVal.canAdd = false
          // 添加新的操作数
          if (oldVal.values[oldVal.values.length - 1].value === '.') return
          oldVal.values[oldVal.values.length] = { operator: v.value, value: '', hasDot: false, reverse: false }
        } else {
          // 更新当前运算符
          oldVal.values[oldVal.values.length - 1].operator = v.value
          // console.log(oldVal.values[oldVal.values.length - 1].operator)
        }
        if (oldVal.values.length > 1) oldVal.canRes = true
        // 设置真实运算符
        oldVal.values[oldVal.values.length - 1].realOperator = getRealOperator(v.value)
        // console.log(oldVal)
        break
      case 'precent':
        // 如果计算已完成，重置状态
        if (oldVal.isFinished) {
          oldVal.values = [{ value: eval(result).toString(), operator: '+', realOperator: '+', hasDot: false, reverse: false }]
          oldVal.canAdd = false
          oldVal.canRes = false
          oldVal.isFinished = false
          setResult('')
        }
        current = oldVal.values[oldVal.values.length - 1]
        // 如果是反转状态则不处理
        if (current.reverse) {
          current.value = current.value.slice(1, -1)
        }
        // 将当前操作数转换为百分比
        current.value = (Number(current.value)*0.01).toString()
        current.hasDot = true
        if (current.reverse) {
          current.value = `(${current.value})`
        }
        oldVal.canAdd = true
        // console.log(oldVal)
        break
      case 'reverse':
        // 如果计算已完成，重置状态
        if (oldVal.isFinished) {
          oldVal.values = [{ value: eval(result).toString(), operator: '+', realOperator: '+', hasDot: false, reverse: false }]
          oldVal.canAdd = false
          oldVal.canRes = false
          oldVal.isFinished = false
          setResult('')
        }
        current = oldVal.values[oldVal.values.length - 1]
        // 如果当前操作数为空则不处理
        if (!current.value) return
        // 反转当前操作数的正负
        current.reverse = !current.reverse
        current.value = current.value.includes('(') ? String(current.value.slice(1, -1) * (-1)) : `(${current.value * (-1)})`
        oldVal.canAdd = true
        // console.log(eval(current.value)*(-1).toString())
        // console.log(oldVal)
        break
    }
    // 更新状态
    setValue(oldVal)
    // 如果可以计算结果，则进行计算
    if (oldVal.canRes) computedResult(oldVal)
  }

  /**
   * 计算当前表达式的结果字符串
   * @param {Object} oldVal - 计算器状态对象
   */
  function computedResult (oldVal) {
    // console.log(oldVal)
    // 拼接计算表达式
    const resultVal = oldVal.values.reduce((res, item, index) => {
      if (!index) {
        res = res + item.value
      } else {
        res = res + item.realOperator +
          (
            item.value
              ? item.value === '.'
                ? '0'
                : item.value
              : item.realOperator === '*' || item.realOperator === '/'
                ? '1'
                : '0'
          )
      }
      return res
    }, '')
    // console.log(resultVal)
    // 更新结果字符串
    setResult(resultVal)
  }

  /**
   * 获取运算符对应的真实运算符
   * @param {string} operator - 显示的运算符
   * @returns {string} - 真实运算符
   */
  function getRealOperator (operator) {
    switch (operator) {
      case '＋':
        return '+'
      case '－':
        return '-'
      case '×':
        return '*'
      case '÷':
        return '/'
    }
  }

  /**
   * 重置计算器状态
   */
  function reset () {
    setValue({
      canAdd: false,
      canRes: false,
      isFinished: false,
      values: [{ value: '', operator: '+', realOperator: '+', hasDot: false, reverse: false}]
    })
    setResult('')
  }

  /**
   * 处理删除按钮点击事件
   */
  function del () {
    const oldVal = {...value}
    // 如果计算已完成，重置状态
    if (oldVal.isFinished) {
      reset()
      return
    }
    const current = oldVal.values[oldVal.values.length - 1]
    switch (true) {
      case current.value.length > 0:
        // 如果当前操作数有字符，删除最后一个字符
        if (current.value.slice(-1) === '.') current.hasDot = false
        if (current.reverse) {
          current.value = eval(current.value).toString().slice(0, -1)
          if (current.value.slice(-1) === '.') {
            current.hasDot = false
            current.value = current.value.slice(0, -1)
          }
          current.value = `(${current.value})`
          if (current.value === '(-)') {
            current.value = ''
            oldVal.canAdd = false
            current.reverse = false
          }
          break
        }
        current.value = current.value.slice(0, -1)
        oldVal.canAdd = true
        break
      case !current.value:
        // 只剩最后一个操作数时
        if (oldVal.values.length === 1) return
        // 如果当前操作数为空，删除最后一个操作数
        oldVal.canAdd = true
        oldVal.values.length--
        if (oldVal.values.length === 1) {
          oldVal.canRes = false
          setResult('')
        }
        break
    }
    // console.log(current.value.slice(-1) === '.')
    // 更新状态
    setValue(oldVal)
    // console.log(oldVal)

    // 如果可以计算结果，则进行计算
    if (oldVal.canRes) computedResult(oldVal)
  }

  return (
    <div className="compute">
      <div style={{ padding: '20rem' }}>计算</div>
      <div className="result">
        <div className={ value.isFinished ? "formvalue complate" : 'formvalue' }>
          {
            value.values.map((v, i) =>
              <React.Fragment key={ i }>
                { i ? <div className="form">{ v.operator }</div> : '' }
                <div className="value">{ v.value }</div>
              </React.Fragment>
            )
          }
        </div>
        <div className={ value.isFinished ? 'fin finished' : 'fin' }>{ eval(result)?.toLocaleString() }</div>
      </div>

      <div className="keys">
        <div onClick={ () => reset() }>AC</div>
        <div className="del" onClick={ del }>&#9249;</div>
        {
          arr.map(v =>
            <div onClick={ () => computedValue(v) } key={ v.value }>{ v.value }</div>
          )
        }
      </div>
    </div>
  )
}

// 导出组件
export default Compute
